package com.mingxingyi.applet.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.mingxingyi.applet.constant.UserLoginConstant;
import com.mingxingyi.applet.pojo.entity.UserInfo;
import com.mingxingyi.applet.properties.WechatProperties;
import com.mingxingyi.applet.service.WechatService;
import com.mingxingyi.base.constant.ResultConstant;
import com.mingxingyi.base.exception.obj.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import cn.hutool.http.HttpUtil;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class WechatServiceImpl implements WechatService {


    //微信服务接口地址
    public static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

    public static final String WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";

    public static final String WX_GET_PHONE_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";

    public static final String WX_GET_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";

    public static final String WX_SEND_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";

    public static final String WX_NOTIFY_STATUS_TEMPLATE_ID="qH1fy2q_cnQN6IUU6pkxV9TvW8YtEVzdfiGgkFxb-_A";

    @Autowired
    private WechatProperties properties;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Override
    public String getOpenid(String code) {
        Map<String, Object> requestParam = getAppConfig();
        requestParam.put("js_code", code);
        String result = HttpUtil.get(WX_LOGIN_URL, requestParam);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (ObjectUtil.isNotEmpty(jsonObject.getInt("errcode"))) {
            throw new BaseException(jsonObject.getInt("errcode"), jsonObject.getStr("errmsg"));
        }
        return jsonObject.getStr("openid");
    }


    @Override
    public String getPhone(String phoneCode) {
        String token = getAccessToken();
        Map<String, Object> param = new HashMap<>();
        param.put("code", phoneCode);
        String result = HttpUtil.post(WX_GET_PHONE_URL + token, JSONUtil.toJsonStr(param));
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (jsonObject.getInt("errcode") != 0) {
            throw new BaseException(jsonObject.getInt("errcode"), jsonObject.getStr("errmsg"));

        }
        //获取手机号
        return jsonObject.getJSONObject("phone_info").getStr("purePhoneNumber");
    }

    @Override
    public String getAccessToken() {
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        String token = stringStringValueOperations.get(UserLoginConstant.WX_ACCESS_TOKEN_REDIS_KEY);
        if (StringUtils.isNotBlank(token)) {
            return token;
        }
        Map<String, Object> requestParam = getAppConfig();
        requestParam.put("grant_type", "client_credential");
        String result = HttpUtil.get(WX_ACCESS_TOKEN_URL, requestParam);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (ObjectUtil.isNotEmpty(jsonObject.getInt("errcode"))) {
            throw new BaseException(jsonObject.getInt("errcode"), jsonObject.getStr("errmsg"));
        }
        //将token保存到缓存中
        String accessToken = jsonObject.getStr("access_token");
        Long expiresIn = jsonObject.getLong("expires_in");
        stringStringValueOperations.set(UserLoginConstant.WX_ACCESS_TOKEN_REDIS_KEY,
                //减去一分钟
                accessToken, expiresIn - 60, TimeUnit.SECONDS);
        return accessToken;
    }

    @Override
    public UserInfo getUserInfo(String token, String openId) {
        Map<String, Object> requestParam = new HashMap<>();
        requestParam.put("access_token", token);
        requestParam.put("openid", openId);
        requestParam.put("lang", "zh_CN");
        String result = HttpUtil.get(WX_GET_USER_INFO_URL, requestParam);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (ObjectUtil.isNotEmpty(jsonObject.getInt("errcode"))) {
            throw new BaseException(jsonObject.getInt("errcode"), jsonObject.getStr("errmsg"));
        }
        UserInfo userInfo=new UserInfo();
        userInfo.setProfileImagePath(jsonObject.getStr("headimgurl"));
        userInfo.setUsername(jsonObject.getStr("nickname"));
        userInfo.setOpenId(openId);
        return userInfo;
    }

    @Override
    public void sendMessage(Map<String, String> data) {
        log.info("发送消息"+JSONUtil.toJsonStr(data));

        String touser = data.get("touser");
        String username = data.get("username");
        String userStatusStr = data.get("user_status_str");
        if(StringUtils.isBlank(username)
        ||StringUtils.isBlank(touser)
        ||StringUtils.isBlank(userStatusStr)){
            return;
        }


        LinkedHashMap<String,Object> dataStr=new LinkedHashMap<>();
        dataStr.put("thing2",new HashMap<String,Object>(){{
            put("value",username);
        }});
        dataStr.put("thing3",new HashMap<String,Object>(){{
            put("value",userStatusStr);
        }});


        String token = getAccessToken();
        String url=WX_SEND_MESSAGE_URL+token;
        Map<String, Object> param = new HashMap<>();
        param.put("template_id", WX_NOTIFY_STATUS_TEMPLATE_ID);
        param.put("touser", touser);
        param.put("data", dataStr);
        param.put("page", "pages/index/index");
        param.put("miniprogram_state", properties.getMiniprogramState());
        param.put("lang", "zh_CN");
        log.info("发送消息请求数据："+JSONUtil.toJsonStr(param));
        String result = HttpUtil.post(url, JSONUtil.toJsonStr(param));
        log.info("发送消息返回结果："+JSONUtil.toJsonStr(result));
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if (ObjectUtil.isNotEmpty(jsonObject.getInt("errcode"))) {
            throw new BaseException(jsonObject.getInt("errcode"), jsonObject.getStr("errmsg"));
        }
    }


    private Map<String, Object> getAppConfig() {
        Map<String, Object> requestParam = new HashMap<>();
        requestParam.put("appid", properties.getAppId());
        requestParam.put("secret", properties.getAppSecret());
        requestParam.put("grant_type", "authorization_code");
        return requestParam;
    }
}
